#include "xCamera.h"
#include  "XRenderSystem.h"
#include "XEngine.h"
#include "xMeshManager.h"
#include "xSceneManager.h"

namespace XE
{


	xCamera::xCamera( xSceneManager* pCreate,const xString& name,xSceneNode* pParent)
		:xSceneNode(pCreate,pParent,name),m_fov(PI/4.0f),m_aspect(1.33f),m_near(1.0f),m_pCreater(pCreate),
		m_far(5000.0f),m_NeedUpDataProject(false),m_NeedUpataeView(false)
	{

	}


	void xCamera::SetFov(float fov)
	{
		m_fov	= fov;
		NeedUpDataProject(true);
	}



	void xCamera::SetAspect(float aspect)
	{
		m_aspect = aspect;
		NeedUpDataProject(true);

	}



	void xCamera::SetNearPlane(float n)
	{
		m_near	= n;
		//m_near=near;
		NeedUpDataProject(true);
	}



	void xCamera::SetFarPlane(float f)
	{
		m_far=f;
		//m_far=far;
		NeedUpDataProject(true);
	}




	/*void xCamera::LookAt(const xVector3& LookAt,const xVector3&up)
	{
	xMath::BuildLookAtMatrix(m_ViewMatrix,m_Position,LookAt,up);
	NeedUpdata(false);

	}*/


	const xMatrix* xCamera::GetProjectMatrix(void )  
	{
		//if(IsNeedUpDataProject())
		//{
		//	NeedUpDataProject(false);
		xMath::BuildProjectMatrix(m_ProjectMatrix,m_fov,m_aspect,m_near,m_far);
		//}

		return &m_ProjectMatrix;
	}



	const xMatrix* xCamera::GetViewMatrix(void) const 
	{

		return &m_ViewMatrix;
	}



	bool xCamera::CaptureOneFrame()
	{

		if(m_pCreater==NULL)
			return false;
		return m_pCreater->CaptureOneFrame(this);
	}


	void  xCamera::update(bool ParentChange,int& upNumber)
	{
		/*bool  tem = false;
		if(ParentChange||m_SafeUpdate)
		{
			tem = true;
		}*/
		xNode::update(ParentChange,upNumber);
	//	if(tem)
		{

			xMath::MatrixInverse(m_ViewMatrix,m_WorldMatrix);
		}
	}



	xRay  xCamera::GetSceneRay(float x,float y)
	{
     	xVector3 target;
		target.x = (2.0f * x) - 1.0f;
		target.y = 1.0f - (2.0f * y);
		target.z = 1.0f;

	

		xVector3 point;
        const xMatrix* pViewMat =GetViewMatrix();
		const xMatrix* pProMat = GetProjectMatrix();
		const xMatrix* pWorldmat = GetWorldMatrix();
		target.x /=pProMat->m[0][0];
		target.y /=pProMat->m[1][1];
		//xMatrix Ivsermat;
	  //  Ivsermat = (*pViewMat)*(*pProMat);
	//	xMath::MatrixInverse(Ivsermat,Ivsermat);

		target=target*(*pWorldmat);
		point.x =pWorldmat->m[3][0];
		point.y =pWorldmat->m[3][1];
		point.z =pWorldmat->m[3][2];
		return xRay(point,target);		

	}




}